/**
 * @Title: LogHandler.java
 * @Package com.mvc.aop
 * @Description: TODO(用一句话描述该文件做什么)
 * @author frinder_liu
 * @date 2015年1月29日 上午12:03:38
 * @version V1.0
 */
package com.beauty.aop;

import com.beauty.entity.BeautyHandlerLogs;
import com.beauty.service.LogService;
import com.beauty.util.StringUtil;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Pointcut;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.amqp.AmqpException;
import org.springframework.amqp.rabbit.core.RabbitTemplate;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

import javax.servlet.http.HttpServletRequest;
import java.util.Date;

/**
 * @author frinder_liu
 * @ClassName: LogHandler
 * @Description: TODO(记录url)
 * @date 2015年9月5日 下午8:57:34
 */
@Component
@Aspect
public class LogHandler {

    private final Logger logger = LoggerFactory.getLogger(LogHandler.class);

    @Autowired
    private HttpServletRequest request;

    // @Resource(name = "logDirectTemplate")
    private RabbitTemplate logDirectTemplate;

    @Autowired
    private LogService logService;

    /**
     *
     */
    public LogHandler() {
    }

    @Pointcut("execution(* com.beauty..*.*(..)) && !execution(* com.beauty.mapper..*.*(..))")
    public void allPointCut() {
    }

    @Pointcut("execution(* com.beauty.controller..*.*(..))")
    public void controllerPointCut() {
    }

    /**
     * print all log
     *
     * @param point
     * @return
     * @throws Throwable
     */
    //@Around("allPointCut()")
    @Around("controllerPointCut()")
    public Object logger(ProceedingJoinPoint point) throws Throwable {
        long bTime = System.nanoTime();
        StringBuilder requestStr = new StringBuilder();
        requestStr.append("HttpServletRequest : ").append("Method {{}}, ").append("URL {{}}, ").append("URI {{}}, ").append("PathInfo {{}}, ").append("QueryString {{}}, ").append("RemoteAddr {{}}, ").append("RemoteHost {{}}, ").append("RemotePort {{}}, ").append("LocalAddr {{}}, ").append("LocalName {{}}, ").append("LocalPort {{}}, ");
        logger.debug(requestStr.toString(), new Object[]{this.request.getMethod(), this.request.getRequestURL(), this.request.getRequestURI(), this.request.getPathInfo(), this.request.getQueryString(), this.request.getRemoteAddr(), this.request.getRemoteHost(), Integer.valueOf(this.request.getRemotePort()), this.request.getLocalAddr(), this.request.getLocalName(), Integer.valueOf(this.request.getLocalPort())});
        logger.debug("ProceedingJoinPoint {{}}, Args {{}}", point, point.getArgs());

        Object result;
        try {
            result = point.proceed();
        } catch (Throwable var8) {
            logger.error(var8.getMessage(), var8);
            throw new Throwable(var8);
        }

        logger.info("response info : {}", result);
        long eTime = System.nanoTime();
        logger.info("take time : {} ns !", Long.valueOf(eTime - bTime));
        return result;
    }

    /**
     * @param point
     * @return
     * @throws Throwable
     */
    // @Around("controllerPointCut()")
    public Object loggerDB(ProceedingJoinPoint point) throws Throwable {
        long beginTime = System.currentTimeMillis();
        Object retValue = point.proceed();
        long endTime = System.currentTimeMillis();
        BeautyHandlerLogs log = convert2Log(point, retValue, beginTime, endTime);
        try {
            this.logDirectTemplate.convertAndSend(log);
        } catch (AmqpException e) {
            logger.error(e.getMessage());
        }
        return retValue;
    }

    /**
     * @param point
     * @param retValue
     * @param beginTime
     * @param endTime
     * @return
     */
    private BeautyHandlerLogs convert2Log(ProceedingJoinPoint point, Object retValue, long beginTime, long endTime) {
        BeautyHandlerLogs log = new BeautyHandlerLogs();
        try {
            log.setAccount(StringUtil.valueOf(request.getSession().getAttribute("CURRENT_USER_ACCOUNT")).concat(":").concat(StringUtil.valueOf(request.getSession().getAttribute("IP"))));
        } catch (Exception e) {
            log.setAccount("account");
        }
        try {
            log.setArgs(StringUtil.valueOf(point.getArgs()));
        } catch (Exception e) {
            log.setArgs("");
        }
        try {
            log.setReturnValue(StringUtil.valueOf(retValue));
        } catch (Exception e) {
            log.setReturnValue("");
        }
        log.setClassName(point.getTarget().getClass().getName());
        log.setMethodName(point.getSignature().getName());
        log.setBeginTime(new Date(beginTime));
        log.setEndTime(new Date(endTime));
        log.setCreateTime(new Date());
        return log;
    }

}
